home *** CD-ROM | disk | FTP | other *** search
/ HAM Radio 3.2 / Ham Radio Version 3.2 (Chestnut CD-ROMs)(1993).ISO / packet / n17jsrc / ax25subr.c < prev    next >
C/C++ Source or Header  |  1991-04-27  |  6KB  |  258 lines

  1. /* low level AX25 routines:
  2.  * callsign conversion
  3.  * control block management
  4.  *
  5.  * Copyright 1991 Phil Karn, KA9Q
  6.  */
  7.  /* Mods by G1EMM */
  8. #include <stdio.h>
  9. #include "global.h"
  10. #include "mbuf.h"
  11. #include "timer.h"
  12. #include "ax25.h"
  13. #include "lapb.h"
  14. #include <ctype.h>
  15.  
  16. struct ax25_cb *Ax25_cb;
  17.  
  18. /* Default AX.25 parameters */
  19. int32 T3init = 0;        /* No keep-alive polling */
  20. int32 T4init = 300;        /* 5 Minutes of no I frame tx or rx => redundant link */
  21. int16 Maxframe = 1;        /* Stop and wait */
  22. int16 N2 = 10;            /* 10 retries */
  23. int16 Axwindow = 2048;        /* 2K incoming text before RNR'ing */
  24. int16 Paclen = 256;        /* 256-byte I fields */
  25. int16 Pthresh = 128;        /* Send polls for packets larger than this */
  26. int32 Axirtt = 5000;        /* Initial round trip estimate, ms */
  27. int16 Axversion = V2;        /* Protocol version */
  28. int32 Blimit = 30;        /* Retransmission backoff limit */
  29.  
  30. /* Look up entry in connection table */
  31. struct ax25_cb *
  32. find_ax25(addr)
  33. register char *addr;
  34. {
  35.     register struct ax25_cb *axp;
  36.     struct ax25_cb *axlast = NULLAX25;
  37.  
  38.     /* Search list */
  39.     for(axp = Ax25_cb; axp != NULLAX25;axlast=axp,axp = axp->next){
  40.         if(addreq(axp->remote,addr)){
  41.             if(axlast != NULLAX25){
  42.                 /* Move entry to top of list to speed
  43.                  * future searches
  44.                  */
  45.                 axlast->next = axp->next;
  46.                 axp->next = Ax25_cb;
  47.                 Ax25_cb = axp;
  48.             }
  49.             return axp;
  50.         }
  51.     }
  52.     return NULLAX25;
  53. }
  54.  
  55. /* Remove address entry from connection table */
  56. void
  57. del_ax25(conn)
  58. struct ax25_cb *conn;
  59. {
  60.     register struct ax25_cb *axp;
  61.     struct ax25_cb *axlast = NULLAX25;
  62.  
  63.     for(axp = Ax25_cb; axp != NULLAX25; axlast=axp,axp = axp->next){
  64.         if(axp == conn)
  65.             break;
  66.     }
  67.  
  68.     if(axp == NULLAX25)
  69.         return;        /* Not found */
  70.  
  71.     /* Remove from list */
  72.     if(axlast != NULLAX25)
  73.         axlast->next = axp->next;
  74.     else
  75.         Ax25_cb = axp->next;
  76.  
  77.     /* Timers should already be stopped, but just in case... */
  78.     stop_timer(&axp->t1);
  79.     stop_timer(&axp->t3);
  80.     stop_timer(&axp->t4);
  81.  
  82.     axp->r_upcall = NULLVFP;
  83.     axp->s_upcall = NULLVFP;
  84.     axp->t_upcall = NULLVFP;
  85.  
  86.     /* Free allocated resources */
  87.     free_q(&axp->txq);
  88.     free_q(&axp->rxasm);
  89.     free_q(&axp->rxq);
  90.     free((char *)axp);
  91. }
  92.  
  93. /* Create an ax25 control block. Allocate a new structure, if necessary,
  94.  * and fill it with all the defaults. The caller
  95.  * is still responsible for filling in the reply address
  96.  */
  97. struct ax25_cb *
  98. cr_ax25(addr)
  99. char *addr;
  100. {
  101.     register struct ax25_cb *axp;
  102.  
  103.     if(addr == NULLCHAR)
  104.         return NULLAX25;
  105.  
  106.     if((axp = find_ax25(addr)) == NULLAX25){
  107.         /* Not already in table; create an entry
  108.          * and insert it at the head of the chain
  109.          */
  110.         axp = (struct ax25_cb *)callocw(1,sizeof(struct ax25_cb));
  111.         /* Insert at beginning of chain */
  112.         axp->next = Ax25_cb;
  113.         Ax25_cb = axp;
  114.     }
  115.     axp->user = -1;
  116.     axp->state = LAPB_DISCONNECTED;
  117.     axp->maxframe = Maxframe;
  118.     axp->window = Axwindow;
  119.     axp->paclen = Paclen;
  120.     axp->proto = Axversion;    /* Default, can be changed by other end */
  121.     axp->pthresh = Pthresh;
  122.     axp->n2 = N2;
  123.     axp->srt = Axirtt;
  124.     set_timer(&axp->t1,2*axp->srt);
  125.     axp->t1.func = recover;
  126.     axp->t1.arg = axp;
  127.  
  128.     set_timer(&axp->t3,T3init);
  129.     axp->t3.func = pollthem;
  130.     axp->t3.arg = axp;
  131.  
  132.     set_timer(&axp->t4,T4init * 1000L);
  133.     axp->t4.func = redundant;
  134.     axp->t4.arg = axp;
  135.  
  136.     /* Always to a receive and state upcall as default */
  137.     /* Also bung in a default transmit upcall - in case */
  138.     axp->r_upcall = s_arcall;
  139.     axp->s_upcall = s_ascall;
  140.     axp->t_upcall = s_atcall;
  141.  
  142.     return axp;
  143. }
  144.  
  145. /*
  146.  * setcall - convert callsign plus substation ID of the form
  147.  * "KA9Q-0" to AX.25 (shifted) address format
  148.  *   Address extension bit is left clear
  149.  *   Return -1 on error, 0 if OK
  150.  */
  151. int
  152. setcall(out,call)
  153. char *out;
  154. char *call;
  155. {
  156.     int csize;
  157.     unsigned ssid;
  158.     register int i;
  159.     register char *dp;
  160.     char c;
  161.  
  162.     if(out == NULLCHAR || call == NULLCHAR || *call == '\0')
  163.         return -1;
  164.  
  165.     /* Find dash, if any, separating callsign from ssid
  166.      * Then compute length of callsign field and make sure
  167.      * it isn't excessive
  168.      */
  169.     dp = strchr(call,'-');
  170.     if(dp == NULLCHAR)
  171.         csize = strlen(call);
  172.     else
  173.         csize = dp - call;
  174.     if(csize > ALEN)
  175.         return -1;
  176.     /* Now find and convert ssid, if any */
  177.     if(dp != NULLCHAR){
  178.         dp++;    /* skip dash */
  179.         ssid = atoi(dp);
  180.         if(ssid > 15)
  181.             return -1;
  182.     } else
  183.         ssid = 0;
  184.     /* Copy upper-case callsign, left shifted one bit */
  185.     for(i=0;i<csize;i++){
  186.         c = *call++;
  187.         if(islower(c))
  188.             c = toupper(c);
  189.         *out++ = c << 1;
  190.     }
  191.     /* Pad with shifted spaces if necessary */
  192.     for(;i<ALEN;i++)
  193.         *out++ = ' ' << 1;
  194.     
  195.     /* Insert substation ID field and set reserved bits */
  196.     *out = 0x60 | (ssid << 1);
  197.     return 0;
  198. }
  199. int
  200. addreq(a,b)
  201. register char *a,*b;
  202. {
  203.     if(memcmp(a,b,ALEN) != 0 || ((a[ALEN] ^ b[ALEN]) & SSID) != 0)
  204.         return 0;
  205.     else
  206.         return 1;
  207. }
  208. /* Convert encoded AX.25 address to printable string */
  209. char *
  210. pax25(e,addr)
  211. char *e;
  212. char *addr;
  213. {
  214.     register int i;
  215.     char c;
  216.     char *cp;
  217.  
  218.     cp = e;
  219.     for(i=ALEN;i != 0;i--){
  220.         c = (*addr++ >> 1) & 0x7f;
  221.         if(c != ' ')
  222.             *cp++ = c;
  223.     }
  224.     if ((*addr & SSID) != 0)
  225.         sprintf(cp,"-%d",(*addr >> 1) & 0xf);    /* ssid */
  226.     else
  227.         *cp = '\0';
  228.     return e;
  229. }
  230.  
  231. /* Figure out the frame type from the control field
  232.  * This is done by masking out any sequence numbers and the
  233.  * poll/final bit after determining the general class (I/S/U) of the frame
  234.  */
  235. int16
  236. ftype(control)
  237. register int control;
  238. {
  239.     if((control & 1) == 0)    /* An I-frame is an I-frame... */
  240.         return I;
  241.     if(control & 2)        /* U-frames use all except P/F bit for type */
  242.         return (int16)(uchar(control) & ~PF);
  243.     else            /* S-frames use low order 4 bits for type */
  244.         return (int16)(uchar(control) & 0xf);
  245. }
  246.  
  247. void
  248. lapb_garbage(red)
  249. int red;
  250. {
  251.     register struct ax25_cb *axp;
  252.  
  253.     for(axp=Ax25_cb;axp != NULLAX25;axp = axp->next){
  254.         mbuf_crunch(&axp->rxq);
  255.         mbuf_crunch(&axp->rxasm);
  256.     }
  257. }
  258.